﻿using System;
using System.Collections.Generic;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class TimeScaleManager : Singleton<TimeScaleManager>
    {
        private TimeScaleManager()
        {
        }

        private const int MaxScaleNum = 64;
        private List<TimeScaleInfo> scale = new List<TimeScaleInfo>(MaxScaleNum);

        private int guidIndex;
        public int AddTimeScale(float scaleValue, ETimeScaleType priority = ETimeScaleType.Lowest)
        {
            var rItem = ClassPool<TimeScaleInfo>.Get();
            rItem.guid = ++guidIndex;
            rItem.priority = (int)priority;
            rItem.value = scaleValue;
            this.scale.Add(rItem);
            this.Refresh();
            return rItem.guid;
        }
        
        public void RemoveTimeScale(int guid)
        {
            for (int i = 0; i < this.scale.Count; i++)
            {
                var rItem = this.scale[i];
                if (rItem.guid == guid)
                {
                    this.scale.RemoveAt(i);
                    ClassPool<TimeScaleInfo>.Put(rItem);
                    break;
                }
            }
            this.Refresh();
        }

        private void Refresh()
        {
            var fScale = 1f;
            if (this.scale.Count > 0)
            {
                var fMax = 1f;
                var fMin = 1f;
                var bIsMax = false;
                var nMaxPriority = -1;
                for (int i = 0; i < this.scale.Count; i++)
                {
                    // 倒序走
                    var rItem = this.scale[this.scale.Count - i - 1];
                    if (rItem.value > fMax)
                    {
                        fMax = rItem.value;
                    }
                    if (rItem.value < fMin)
                    {
                        fMin = rItem.value;
                    }
                    if (rItem.priority > nMaxPriority)
                    {
                        bIsMax = rItem.value > 1;
                    }
                }
                fScale = bIsMax ? fMax : fMin;
            }
            Time.timeScale = fScale;
        }

        private class TimeScaleInfo : IReusableClass
        {
            public int guid;
            public int priority;
            public float value;
            public uint MaxStore => MaxScaleNum;
            public void OnReset()
            {
                this.guid = default;
                this.priority = default;
                this.value = default;
            }
        }
        
    }

    public enum ETimeScaleType
    {
        Max,
        BattleAcc,
        StoryAcc,
        Lowest = int.MaxValue,
    }
}